home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld Secrets (4th Edition)
/
Mac Secrets CD 4th Ed.toast
/
Shareware & Freeware
/
KeyQuencer 1.2.2
/
Developer’s toolkit
/
Common code
/
Extension.h
< prev
next >
Wrap
Text File
|
1995-12-16
|
24KB
|
422 lines
// =============================================================================
// KEYQUENCER EXTENSIONS HEADER - VERSION 1.2.2 - DECEMBER 1995
// By Alessandro Levi Montalcini <alm@torino.alpcom.it>
// ©1994-96 Binary Software, Inc. <binarysoft@eworld.com>
// Don't forget to send us any cool extensions you create!
// This text looks best in monaco 9 font, 4 spaces per tab, no wrapping
//==============================================================================
// Note that all the public interfaces that shipped with 1.2.1 are still good.
// If you want to gain access to a KeyQuencer GluePtr from external software,
// use the KQGestalt.c file provided with the new dev kit; it's a small piece of
// code that works with both 1.2.X and 2.0 and returns a valid GluePtr or NIL.
//==============================================================================
#pragma once
#ifndef _H_extension
#define _H_extension
#ifndef __APPLEEVENTS__
#include <AppleEvents.h>
#endif
//==============================================================================
#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=mac68k
#endif
// =============================================================================
// FORMAT OF THE MAIN ROUTINE FOR A KEYQUENCER EXTENSION:
// pascal short main(long message, ParamsPtr params, MachineHandle mac, GluePtr glue);
typedef struct ParamsRec ParamsRec, *ParamsPtr;
typedef struct MachineRec MachineRec, *MachinePtr, **MachineHandle;
typedef struct GlueRec GlueRec, *GluePtr;
typedef struct EvtFilterRec EvtFilterRec, *EvtFilterRecPtr;
typedef pascal short (*ExtProcPtr) (long message, ParamsPtr params, MachineHandle mac, GluePtr glue);
typedef pascal Boolean (*EvtFilterProcPtr) (EventRecord *event, MachineHandle mac, GluePtr glue);
typedef pascal OSErr (*FinderSelHandler) (long count, FSSpec items[], long reference, GluePtr glue);
// =============================================================================
// CONSTANTS AND RESOURCE TYPES:
#define kExtensionResType 'KQex' // the extension res name (not file name)
// is used by the macro interpreter
#define kExtensionFileType 'KQex' // extension file type
#define kExtensionCreator 'KQen' // extension file creator (standard icon)
#define kMaxExtParams 32 // max # of parameters passed to an extension
#define kMaxScreens 3 // max # of screens in the MachineRec record
#define kKeyFlowHPos -19715 // key events are ignored by KeyQuencer if
#define kKeyFlowVPos -19949 // event.where=={kKeyFlowHPos,kKeyFlowVPos}
// =============================================================================
// MESSAGES (sent to the extension):
enum {
kExtMessageInit = 'INIT', // setup extension, load resources;
// no ParamsPtr available here
kExtMessageRun = 'RUN ' // run extension; the extension resource file
// is already closed
};
// WARNING: GLUE WAS NOT AVAILABLE AT INITIALIZE TIME IN KEYQUENCER 1.0 (now it is)
// Check for nil glue before using glue routines in your kExtMessageInit handler
// =============================================================================
// RESULT CODES (returned by the extension):
enum {
kExtNoError = 0, // no error
kExtCallMeAgain, // keep calling the extension over and over
kExtCallMeAgainLater, // call the extension again after all other
// queued commands have executed
kExtUserAbortedMacro = 100, // code returned by LastMacroError when the
// user aborts a macro with cmd-shift-return
kExtGenericError = 256, // positive results >= 256 stop macro execution
kExtBadEnvironment, // without informing the user (you may use
kExtBadParameters, // DisplayMessage or DisplayError to do so)
kExtTooManyParams,
kExtNotEnoughParams,
kExtUnknownKeyword,
kExtWrongApplication,
kExtNotEnoughMemory,
kExtObsoleteKeyQuencer,
kExtRequiresAppleEvents,
kTellGenericError = -256, // negative results stop macro execution
kTellBadEnvironment, // and show a standard error message
kTellBadParameters,
kTellTooManyParams,
kTellNotEnoughParams,
kTellUnknownKeyword,
kTellWrongApplication,
kTellNotEnoughMemory,
kTellObsoleteKeyQuencer,
kTellRequiresAppleEvents
};
// =============================================================================
// CURRENT RECORD VERSIONS (will increase as I append more items to the records):
enum {
kCurParamsRecVers = 1,
kCurMachineRecVers = 1,
kCurGlueRecVers = 6, // check the glue record version before using it
kCurRoutineCount = 48 // number of callback routines in the glue
};
// =============================================================================
// RECORD DEFINITIONS:
// The current record contents will not be modified in future versions
// although more items may be appended at the bottom of each record
struct ParamsRec {
short paramsRecVers; // kCurParamsRecVers
short paramsCount; // number of parameters passed
long countCalls; // this field is initially set to 0,
// incremented at each kExtCallMeAgain,
// always 1 after kExtCallMeAgainLater
long firstCallTicks; // TickCount() of first time called
// (reset when result != kExtCallMeAgain)
short extensionKey; // keyCode<<8 + charCode (low word of
// event.message of key down event)
short extensionModifiers; // event.modifiers of the key down event
// that invoked the macro
long systemMemoryUsed; // you should add to this field the size of
// any static handles and resources that
// you allocate during kExtMessageInit
StringPtr parameter[kMaxExtParams]; // parameters are passed as read-only
// pascal strings (including quotes if any);
// all parameter processing is done by
// the extension itself
};
struct MachineRec {
short machineRecVers; // kCurMachineRecVers
short systemVersion; // system version in BCD format
short screenCount; // # of screens connected to this machine
short mainScreen; // index of main screen in screenBounds array
Rect screenBounds[kMaxScreens]; // bounds of all available screens
// (call UpdateMachineRec to validate bounds)
Boolean hasGestalt; // 01
Boolean hasWaitNextEvent; // 02
Boolean hasAppleEvents; // 03
Boolean has68020; // 04
Boolean hasFPU; // 05
Boolean hasColorQD; // 06 all these flags are automatically
Boolean has32BitQD; // 07 set up by KeyQuencer so the extensions
Boolean hasFSSpec; // 08 don't have to call Gestalt all the time
Boolean hasNewStdFile; // 09
Boolean hasNotification; // 10
Boolean hasAliases; // 11
Boolean hasFindFolder; // 12
Boolean hasPartialRes; // 13
Boolean hasSoundManager; // 14
};
struct GlueRec {
short glueRecVers; // check this before using recent callbacks
short routineCount; // don't check this
pascal void (*DisplayMessage) (ConstStr255Param message, Boolean playBeep);
pascal void (*DisplayError) (OSErr error);
pascal void (*StopSequence) (void);
pascal void (*TypeString) (ConstStr255Param string);
pascal void (*TypeText) (const unsigned char *text, short length);
pascal Boolean (*SafePostEvent) (const EventRecord *event);
pascal void (*WaitTicks) (long pause);
pascal short (*ExecuteScript) (Handle text);
pascal Boolean (*ExtensionAvailable) (ConstStr255Param name);
pascal void (*GetCharacterInfo) (unsigned char c, short *message, short *modifiers);
pascal Boolean (*TrapAvailable) (short trap);
pascal void (*ShowStartupIcon) (short iconID);
pascal void (*AnonymousMessage) (ConstStr255Param message, Boolean playBeep);
// the following routines are only available in glue version 2 or later (KQ 1.1 or later);
// make sure that glue->glueRecVers >= 2 before using them:
pascal Boolean (*AppleEventsAvail) (void);
pascal Boolean (*SendAppleEvent) (const AppleEvent *event, OSErr *errPtr, Boolean bringToFront);
pascal Boolean (*WindowsAvailable) (void);
pascal Boolean (*MacroRunning) (void);
pascal Boolean (*EqualStringPartial) (ConstStr255Param strToFind, ConstStr255Param strToSearch, Boolean caseSens, Boolean partialMatch);
pascal long (*SearchString) (ConstStr255Param strToFind, const unsigned char *buffer, long size, Boolean caseSens);
// the following routines are only available in glue version 3 or later (KQ 1.2 or later);
// make sure that glue->glueRecVers >= 3 before using them:
pascal WindowRef (*RealFrontWindow) (Boolean *isModalDialog);
pascal WindowRef (*RealNextWindow) (WindowRef baseWindow, Boolean *isModalDialog);
pascal Boolean (*RealWindow) (WindowRef window, Boolean *isModalDialog);
pascal OSErr (*FindKQExtFolder) (short *vRefNum, long *dirID);
pascal short (*OpenExtResFile) (void);
pascal void (*UpdateMachineRec) (void);
pascal Boolean (*AskQuestion) (ConstStr255Param question, ConstStr255Param okButtonTitle, ConstStr255Param cancelButtonTitle, short defaultButton, short numTextLines);
pascal Boolean (*AskString) (ConstStr255Param question, StringPtr answer, ConstStr255Param okButtonTitle, ConstStr255Param cancelButtonTitle, short defaultButton, short numInputLines);
// ==================== KeyQuencer 1.2.2 required below this point ====================
// the following routines are only available in glue version 5 or later (KQ 1.2.2 or later);
// make sure that glue->glueRecVers >= 5 before using them:
pascal short (*CountMacros) (void);
pascal Ptr (*BuildSortedIndex) (void);
pascal void (*GetMacroInfo) (short macroIndex, unsigned char *macroName, short *keyCode, short *modifiers);
pascal Handle (*GetIndexedMacro) (short macroIndex);
pascal Handle (*GetNamedMacro) (ConstStr31Param macroName);
// ===================== KeyQuencer 2.0 required below this point =====================
// the following routines are only available in glue version 6 or later (KQ 2.0 or later);
// make sure that glue->glueRecVers >= 6 before using them:
pascal Boolean (*IsLiteralParameter) (ConstStr255Param sourceParameter, StringPtr destString, short maxLength);
pascal Boolean (*IsNumericParameter) (ConstStr255Param sourceParameter, long *destNum, Boolean acceptNegative);
pascal Boolean (*ProcessFinderSel) (FinderSelHandler handler, long reference, OSErr *errptr);
pascal Boolean (*KQAppleEventsBusy) (void);
pascal OSErr (*ExtractFileSpecs) (ParamsPtr params, ConstStr255Param key1, ConstStr255Param key2, FSSpecPtr spec1, FSSpecPtr spec2, short defaultSpec);
pascal void (*HoldDownModifiers) (short modifiers);
pascal void (*ReleaseModifiers) (void);
pascal void (*InstallEventFilter) (EvtFilterRecPtr eventFilter);
pascal void (*RemoveEventFilter) (EvtFilterRecPtr eventFilter);
pascal DialogRef (*GetDetachedDialog) (Handle dlog, Handle ditl, WindowRef behind);
pascal short (*LastMacroError) (void);
pascal long (*GetVariable) (ConstStr255Param variableName, StringPtr variableValue);
pascal long (*SetVariable) (ConstStr255Param variableName, ConstStr255Param variableValue);
pascal long (*ClearVariable) (ConstStr255Param variableName);
pascal long (*CountVariables) (void);
pascal long (*GetIndexedVariable) (long variableIndex, StringPtr variableValue);
};
struct EvtFilterRec {
EvtFilterRecPtr nextFilter; // for use by KQ only - always initialize to zero
EvtFilterProcPtr filterProc; // pointer to your event filter procedure
};
// =============================================================================
// GLUE - QUICK REFERENCE:
/*
DisplayMessage: Displays a message (pascal string) via the notification mgr,
optionally plays a system beep.
DisplayError: Displays an error (common OSErr's are shown by name in KQ 1.2).
StopSequence: Stops all macros and flushes the queue (same as cmd-shift-return).
TypeString: Types a pascal string as if the user was typing it from the keyboard.
TypeText: Same as TypeString, takes a buffer instead of a pascal string.
SafePostEvent: Checks the event queue and posts an event if it isn't already full
(use this instead of PPostEvent); returns true if everything OK.
WaitTicks: Pauses macro execution for some time after the extension has returned.
ExecuteScript: Executes a macro (the macro text is passed in a handle);
returns 0 if the macro was successfully queued,
nonzero if an error was found (this is an internal error code).
ExtensionAvailable: Checks if an extension was loaded at startup.
GetCharacterInfo: Returns the keyCode, charCode and modifiers needed to type
a given character with a keyDown event.
TrapAvailable: Checks if a trap is available (returns true if it is, false otherwise).
ShowStartupIcon: Displays a startup icon (this only works at startup time,
when the init message is received by the extension).
AnonymousMessage: Displays a message (pascal string) without the extension name.
// the following routines are only available in glue version 2 or later (KQ 1.1 or later);
// make sure that glue->glueRecVers >= 2 before using them:
AppleEventsAvail: Returns true if the Engine process is running, false otherwise;
SendAppleEvent can do without the Engine process under KQ 1.2 or later.
SendAppleEvent: Sends an Apple Event; the AppleEvent record is duplicated so it can
be allocated on the stack, while the event data handle must be in
the system zone and is disposed of automatically by SendAppleEvent;
never call AEDisposeDesc on the AppleEvent after passing it to
SendAppleEvent, since it's already called by KeyQuencer for you;
*errPtr is set to 1 right away, and receives the error code when
the event is later sent (pass nil if you don't care, but don't wait
for this value to change inside a loop because the Engine process will
wait and send the event when it gets some CPU time at WaitNextEvent);
if bringToFront is true, the receiving application is switched to
the foreground before the event is sent; SendAppleEvent returns
true if the event was successfully queued (not sent), false otherwise.
WindowsAvailable: Returns true if QuickDraw and the Window Manager have been initialized.
MacroRunning: Returns true if KeyQuencer has more extensions to call or keystrokes
to type inside its internal queues.
EqualStringPartial: Compares two strings with optional case sensitivity and partial
matching (strToFind is a subset of strToSearch); returns true if equal.
SearchString: Searches a string inside a buffer with optional case sensitivity;
returns the offset of the first matching character, or a negative
number if no match was found.
// the following routines are only available in glue version 3 or later (KQ 1.2 or later);
// make sure that glue->glueRecVers >= 3 before using them:
RealFrontWindow: Returns the frontmost "real" window (uses RealWindow to filter
out weird windows and floating palettes).
RealNextWindow: Returns the next "real" window behind a given base window.
RealWindow: Returns false for floating palettes, the desktop and other weird
windows (this is an educated guess, not 100% reliable).
FindKQExtFolder: Finds the volume reference number and directory ID of the
"KeyQuencer Extensions" folder.
OpenExtResFile: Opens the extension resource file; please don't use this if you can
do without, since PowerBook users hate to have the HD spin up
(the opened file is NOT guaranteed to be the same file that was
loaded at startup: it may be an updated version, or another file
with the same name that was copied into the "KeyQuencer Extensions"
folder); returns refnum of resfile, or -1 if the file can't be opened.
UpdateMachineRec: Updates the machine record (the screen information fields may change
after startup with the new Multiple Scan monitors).
AskQuestion: Displays an ok/cancel dialog and returns true if the "ok" button was
pressed; returns false when the user cancels and when an error occurs;
pass nil or an empty string to get the default button titles.
AskString: Displays a dialog with an editable text whose contents are copied
from and passed back to the "answer" parameter; returns the same
values you get from AskQuestion.
// ==================== KeyQuencer 1.2.2 required below this point ====================
// the following routines are only available in glue version 5 or later (KQ 1.2.2 or later);
// make sure that glue->glueRecVers >= 5 before using them:
CountMacros: Returns the number of KeyQuencer macros that are currently installed.
BuildSortedIndex: IMPORTANT: THE RETURNED POINTER IS CREATED IN THE SYSTEM HEAP AND MUST BE
DISPOSED BY THE PROGRAM THAT REQUESTED IT.
Creates an array of macro indexes that can be used to get the macros in
alphabetical order (based on the macro names). There are CountMacros
short words in the array, stored in a pointer in the system heap. You
must call DisposePtr on the returned pointer when you're done with it.
GetMacroInfo: Given a zero-based index (from 0 to CountMacros-1), this call returns the
macro name (a pascal string with up to 31 characters), the macro's key code
(in the high byte of the returned word) and the macro's keystroke modifiers.
Each of the three pointers may be NIL if you don't want the related data.
GetIndexedMacro: IMPORTANT: THE RETURNED HANDLE IS CREATED IN THE SYSTEM HEAP AND MUST BE
DISPOSED BY THE PROGRAM THAT REQUESTED IT.
Returns a handle containing the text of the nth macro, where n is a zero-
based index (from 0 to CountMacros-1). Returns NIL if no such macro exists.
Use DisposeHandle on the returned handle when you're done with it.
GetNamedMacro: IMPORTANT: THE RETURNED HANDLE IS CREATED IN THE SYSTEM HEAP AND MUST BE
DISPOSED BY THE PROGRAM THAT REQUESTED IT (it used to be read-only in 2.0b2)
Returns a handle containing the text of the macro whose name matches
the "macroName" parameter; the name comparison is case-insensitive.
Returns NIL if no macro with the given name is found. Use DisposeHandle on
the returned handle when you're done with it.
// ===================== KeyQuencer 2.0 required below this point =====================
// the following routines are only available in glue version 6 or later (KQ 2.0 or later);
// make sure that glue->glueRecVers >= 6 before using them:
IsLiteralParameter: Checks if a parameter begins and ends with quotes; if so, it copies the
unquoted literal to a destination string, up to a maximum of maxLength
characters (plus one length byte at the beginning of the string).
IsNumericParameter: Checks if a parameter is an integer number, accepts negative numbers
if acceptNegative is true; if it's a number, then the numeric value
is copied in destValue and the function returns true.
ProcessFinderSel: Gets the current Finder selection and processes each item with the
provided handler; the handler is not called right away, since the Engine
process has to wait for the Finder's reply to a "get selection" event;
the disposer is called once after the handler has been called for each
selected item, so you get a chance to dispose of anything you stored in
the reference parameter (which can be used freely); errptr behaves
like in SendAppleEvent; the result is true if the handler was queued
(requires the Engine process and Finder 7.5 or later).
KQAppleEventsBusy: Returns true if the KeyQuencer Engine Process is busy (i.e. if it has
pending Apple Events in its queues).
ExtractFileSpecs: Interprets and removes file specifications from the parameters record
passed to the extension; key1 and key2 are the keywords of the extension
parameters (such as "from" and "to") that specify the usage of the file
specifications; key1 is used by default if no key is found in the macro;
defaultSpec is the number of the FSSpec to fill if no key is found (1 or
2), or zero if a key is always required; the vRefNum of the FSSpec
returned is 0 if no file was specified in the macro; the following
parameters are removed from the ParamsRec: any literal parameter,
clipboard, sysdisk, panels, apple, system, desktop, trash, extensions,
preferences, startup (plus key1 and key2).
HoldDownModifiers: Disables all ADB devices whose original ADB address is 2 (which is the
original address of all Apple keyboards) and updates the low-memory
key map so that the desired modifier keys are held down; must be
followed by a call to ReleaseModifiers, or the keyboard stays dead.
ReleaseModifiers: Releases the modifier keys that were pressed by a previous call to
HoldDownModifiers and re-enables the disabled ADB devices.
InstallEventFilter: Installs an event filter procedure that gets called before KeyQuencer
does its own event filtering; event filters can be installed and removed
at any time (not only at startup) and should return true if the event
they received must be killed (i.e. turned into a null event); note: the
safest time to call RemoveEventFilter is from the filter itself (see below);
the EvtFilterRec is owned by KeyQuencer until the filter is removed, and
it can't be moved or disposed of (don't allocate it as a local variable
on the stack!); it contains a pointer to the event filter routine and a
pointer to the next EvtFilterRec which should be initialized to zero and
never touched again, since it's used by KeyQuencer to build a linked list.
RemoveEventFilter: Removes an event filter procedure that was previously installed; it is
usually a good idea to call RemoveEventFilter from inside the event filter
itself, since the extension's "run" routine may not be called again even
if you returned kExtCallMeAgain (the user could have stopped the macro
before the extension was called again).
GetDetachedDialog: Behaves pretty much like GetNewDialog, except you pass it the handles to
a DLOG template and a DITL template that you previously loaded into memory
(typically at startup via GetResource + DetachResource). The DITL template
is duplicated before being used, so that your copy of the handle is not
disposed of when the dialog is later closed (since DisposeDialog frees up
the memory used by the items list). Use DisposeDialog (not CloseDialog)
to close the dialog when you're done with it.
LastMacroError: Returns the last error code returned by an extension or by the macro
interpreter. Zero means no error, values > 256 or < 0 are extension
errors, and small positive values are private error codes returned by
the macro interpreter (syntax errors, etc). The kExtCallMeAgain and
kExtCallMeAgainLater codes are reported as kExtNoError (i.e. zero).
GetVariable: Gets the value of a KeyQuencer variable. Returns the variable index or
a negative value if the variable was not found. The variable name
should not include the "$", "&" or "%" prefixes since these are stripped
and used at runtime by the macro processor to quote the value if needed
(the same rule applies to all the other variable routines as well).
SetVariable: Creates a KeyQuencer variable if no variable exists with the given name,
then sets its value to the specified string. Returns the variable index
or a negative value if an error occurred.
ClearVariable: Removes a variable. If variableName is NIL, all variables are removed.
Returns the number of variables that were successfully removed.
CountVariables: Returns the number of KeyQuencer variables that are currently defined.
GetIndexedVariable: Same as GetVariable except it uses a numeric index instead of the name.
Returns a negative value if the given index is out of range.
*/
// =============================================================================
#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=reset
#endif
//==============================================================================
#endif // _H_extension
// =============================================================================